package cn.iocoder.yudao.module.bpm.framework.flowable.core.listener.demo.exection;

import cn.iocoder.yudao.module.bpm.controller.admin.projectinfo.vo.BpmProjectInfoSaveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.taskinfo.vo.BpmTaskInfoCheckStatusVO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.taskinfo.BpmTaskInfoDO;
import cn.iocoder.yudao.module.bpm.enums.projectinfo.BpmProjectInfoStatusEnum;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
import cn.iocoder.yudao.module.bpm.service.projectinfo.BpmProjectInfoService;
import cn.iocoder.yudao.module.bpm.service.taskinfo.BpmTaskInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Objects;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * 流程结束时同步任务状态
 *
 * 和 {@link DemoDelegateClassExecutionListener} 的差异是，需要注册到 Spring 中，但不用实现 {@link org.flowable.engine.delegate.JavaDelegate} 接口
 */
@Component
@Slf4j
public class DemoSpringExpressionExecutionListener {

    @Resource
    private BpmTaskInfoService bpmTaskInfoService;
    @Resource
    private BpmProjectInfoService bpmProjectInfoService;

    public void execute(DelegateExecution execution) {
        log.info("[execute][execution({}) 流程结束时，执行器被调用！变量有：{}]", execution.getId(),
                execution.getCurrentFlowableListener().getFieldExtensions());
        String processInstanceId = execution.getProcessInstanceId();
        if (StringUtils.isNotBlank(processInstanceId)){
            BpmTaskInfoDO taskInfo = bpmTaskInfoService.getTaskInfoByProcInstId(processInstanceId);
            if (Objects.nonNull(taskInfo) && taskInfo.getEndTime().isBefore(LocalDateTime.now())){
                bpmTaskInfoService.updateTaskInfoStatus(taskInfo.getId(), BpmProcessInstanceStatusEnum.OVERDUE_FINISHED.getStatus());
            }else if (Objects.nonNull(taskInfo) && !Objects.equals(taskInfo.getStatus(), BpmProcessInstanceStatusEnum.OVERDUE.getStatus())){
                bpmTaskInfoService.updateTaskInfoStatus(taskInfo.getId(), BpmProcessInstanceStatusEnum.APPROVE.getStatus());
            }
            //判断是否将项目的状态修改为已完成
            BpmTaskInfoCheckStatusVO checkStatus = bpmTaskInfoService.checkTaskStatusInfo(taskInfo.getProjectId(),getLoginUserId());
            if (Boolean.TRUE.equals(checkStatus.getIsFinished())){
                BpmProjectInfoSaveReqVO projectVo = new BpmProjectInfoSaveReqVO();
                projectVo.setId(taskInfo.getProjectId());
                projectVo.setStatus(BpmProjectInfoStatusEnum.FINISHED.getStatus());
                bpmProjectInfoService.updateProjectInfo(projectVo);
            }
        }else {
            log.warn("[execute][execution({}) 流程结束时，执行器被调用！但是流程实例id为空]", execution.getId());
        }
    }

}